package cn.ztelovecly.springboot.framework.util;

import cn.ztelovecly.springboot.framework.util.excel.Excel;
import cn.ztelovecly.springboot.framework.util.excel.OldExcel;
import cn.ztelovecly.springboot.framework.util.excel.datatable.DataTable;
import com.aliyun.openservices.oss.OSSClient;
import com.aliyun.openservices.oss.model.ObjectMetadata;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Properties;

public class ExportUtil<T> {
    protected Logger logger = LoggerFactory.getLogger(this.getClass());
    public enum FileType {
        XLS,
        XLSX,
    }

    public String upload(DataTable<T> table, Long tenantId,Long id) {
        return upload(table, tenantId, id, FileType.XLSX);
    }

    public String upload(DataTable<T> table, Long tenantId,Long id, FileType fileType) {
        List list;

        String bucketName = "";
        String urlPath = "";
        String AccessKeyId = "";
        String AccessKeySecret = "";

        Properties prop = new Properties();
        InputStream in = Object.class.getResourceAsStream("/setting.properties");
        if(in == null){
            in = SettingUtil.getCaller(3).getResourceAsStream("/setting.properties");
        }
        try {
            prop.load(in);
            bucketName = prop.getProperty("aliyun.oss.bucket.name").trim();
            urlPath = prop.getProperty("aliyun.oss.url").trim();
            AccessKeyId = prop.getProperty("aliyun.accesskey.id").trim();
            AccessKeySecret = prop.getProperty("aliyun.accesskey.secret").trim();
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
//            e.printStackTrace();
        }

        // 初始化一个OSSClient
        OSSClient client;
//        if (!"production".equals(prop.getProperty("deploy.mode"))) {
//            // 初始化一个OSSClient(非生产环境不需要设置服务器地址)
//            client = new OSSClient(AccessKeyId, AccessKeySecret);
//        } else {
//            // 初始化一个OSSClient（生产环境设置阿里云的内网地址）
//            client = new OSSClient("http://oss-cn-hangzhou-internal.aliyuncs.com", AccessKeyId, AccessKeySecret);
//        }

        if(!"internal".equals(prop.getProperty("aliyun.oss.network"))){
            // 初始化一个OSSClient(非生产环境不需要设置服务器地址)
            client = new OSSClient(AccessKeyId, AccessKeySecret);
        }else{
            // 初始化一个OSSClient（生产环境设置阿里云的内网地址）
            client = new OSSClient("http://oss-cn-hangzhou-internal.aliyuncs.com",AccessKeyId, AccessKeySecret);
        }

        String outputFilePath;
        byte[] bytes;
        if(fileType == FileType.XLSX) {
            outputFilePath = tenantId + "/tmp/" + id + ".xlsx";
            try {
                bytes = new Excel(false, table).getBytes();
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
//                e.printStackTrace();
                return null;
            }
        } else {
            outputFilePath = tenantId + "/tmp/" + id + ".xls";
            try {
                bytes = new OldExcel(false, table).getBytes();
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
//                e.printStackTrace();
                return null;
            }
        }
        InputStream content = new ByteArrayInputStream(bytes);

        // 创建上传Object的Metadata
        ObjectMetadata meta = new ObjectMetadata();

        // 必须设置ContentLength
        meta.setContentLength(bytes.length);

        // 上传Object.
        client.putObject(bucketName, outputFilePath, content, meta);

        String fileUrl = urlPath + outputFilePath;
        return fileUrl;
    }

    public String upload(DataTable<T> table, Long tenantId,String moduleName, FileType fileType) {
        String bucketName = "";
        String urlPath = "";
        String AccessKeyId = "";
        String AccessKeySecret = "";
        String EndPoint="";

        Properties prop = new Properties();
        InputStream in = Object.class.getResourceAsStream("/setting.properties");
        if(in == null){
            in = SettingUtil.getCaller(3).getResourceAsStream("/setting.properties");
        }
        try {
            prop.load(in);
            bucketName = prop.getProperty("aliyun.oss.bucket.name").trim();
            urlPath = prop.getProperty("aliyun.oss.url").trim();
            AccessKeyId = prop.getProperty("aliyun.accesskey.id").trim();
            AccessKeySecret = prop.getProperty("aliyun.accesskey.secret").trim();
            EndPoint=prop.getProperty("aliyun.endpoint").trim();
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
//            e.printStackTrace();
        }

        OSSClient client;

        if(!"internal".equals(prop.getProperty("aliyun.oss.network"))){
            // 初始化一个OSSClient(非生产环境不需要设置服务器地址)
            client = new OSSClient(AccessKeyId, AccessKeySecret);
        }else{
            // 初始化一个OSSClient（生产环境设置阿里云的内网地址）
            client = new OSSClient(EndPoint,AccessKeyId, AccessKeySecret);
        }

        String outputFilePath;
        byte[] bytes;

        String fileName = moduleName + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());

        if(fileType == FileType.XLSX) {
            outputFilePath = tenantId + "/tmp/" + fileName + ".xlsx";
            try {
                bytes = new Excel(false, table).getBytes();
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
//                e.printStackTrace();
                return null;
            }
        } else {
            outputFilePath = tenantId + "/tmp/" + fileName + ".xls";
            try {
                bytes = new OldExcel(false, table).getBytes();
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
//                e.printStackTrace();
                return null;
            }
        }
        InputStream content = new ByteArrayInputStream(bytes);

        // 创建上传Object的Metadata
        ObjectMetadata meta = new ObjectMetadata();

        // 必须设置ContentLength
        meta.setContentLength(bytes.length);

        // 上传Object.
        client.putObject(bucketName, outputFilePath, content, meta);

        return urlPath + outputFilePath;
    }

    /**
     * @param beanList
     * @param tenantId
     * @return
     */
    public String upload(List<T> beanList, Long tenantId,Long id) {
        try {
            DataTable<T> table = new DataTable<>(beanList);
            return upload(table, tenantId, id, FileType.XLSX);
        } catch(Exception e) {
            logger.error(e.getMessage(), e);
//            e.printStackTrace();
        }
        return null;
    }

    /**
     * @param beanList
     * @param tenantId
     * @return
     */
    public String upload(List<T> beanList, Long tenantId, String moduleName) {
        try {
            DataTable<T> table = new DataTable<>(beanList);
            return upload(table, tenantId, moduleName, FileType.XLSX);
        } catch(Exception e) {
            logger.error(e.getMessage(), e);
//            e.printStackTrace();
        }
        return null;
    }

    /**
     * @param beanList
     * @param tenantId
     * @return
     */
    public String upload(List<T> beanList, Long tenantId,Long id, FileType type) {
        try {
            DataTable<T> table = new DataTable<>(beanList);
            return upload(table, tenantId, id, type);
        } catch(Exception e) {
            logger.error(e.getMessage(), e);
//            e.printStackTrace();
        }
        return null;
    }

    public String uploadWeb(List<T> beanList, Long tenantId,Long id) {

        String bucketName = "";
        String urlPath = "";
        String AccessKeyId = "";
        String AccessKeySecret = "";
        String EndPoint="";

        Properties prop = new Properties();
        InputStream in = getCaller(4).getResourceAsStream("/setting.properties");
        try {
            prop.load(in);
            bucketName = prop.getProperty("aliyun.oss.bucket.name").trim();
            urlPath = prop.getProperty("aliyun.oss.url").trim();
            AccessKeyId = prop.getProperty("aliyun.accesskey.id").trim();
            AccessKeySecret = prop.getProperty("aliyun.accesskey.secret").trim();
            EndPoint=prop.getProperty("aliyun.endpoint").trim();
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
//            e.printStackTrace();
        }

        // 初始化一个OSSClient
        OSSClient client;
        if (!"production".equals(prop.getProperty("deploy.mode"))) {
            // 初始化一个OSSClient(非生产环境不需要设置服务器地址)
            client = new OSSClient(AccessKeyId, AccessKeySecret);
        } else {
            // 初始化一个OSSClient（生产环境设置阿里云的内网地址）
            client = new OSSClient(EndPoint, AccessKeyId, AccessKeySecret);
        }

        String outputFilePath = tenantId + "/tmp/" + id + ".xlsx";
        String fileUrl = urlPath + outputFilePath;

        DataTable<T> table;
        byte[] bytes;
        try {
            table = new DataTable<>(beanList);
            bytes = new Excel(false, table).getBytes();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
//            e.printStackTrace();
            return null;
        }
        InputStream content = new ByteArrayInputStream(bytes);

        // 创建上传Object的Metadata
        ObjectMetadata meta = new ObjectMetadata();

        // 必须设置ContentLength
        meta.setContentLength(bytes.length);

        // 上传Object.
        client.putObject(bucketName, outputFilePath, content, meta);

        return fileUrl;
    }

    public String upload(Excel excel, Long tenantId,Long id) {
        return upload(excel, tenantId, id, FileType.XLSX);
    }

    public String upload(Excel excel, Long tenantId,Long id, FileType fileType) {
        List list;

        String bucketName = "";
        String urlPath = "";
        String AccessKeyId = "";
        String AccessKeySecret = "";
        String EndPoint="";

        Properties prop = new Properties();
        InputStream in = Object.class.getResourceAsStream("/setting.properties");
        if(in == null){
            in = SettingUtil.getCaller(3).getResourceAsStream("/setting.properties");
        }
        try {
            prop.load(in);
            bucketName = prop.getProperty("aliyun.oss.bucket.name").trim();
            urlPath = prop.getProperty("aliyun.oss.url").trim();
            AccessKeyId = prop.getProperty("aliyun.accesskey.id").trim();
            AccessKeySecret = prop.getProperty("aliyun.accesskey.secret").trim();
            EndPoint=prop.getProperty("aliyun.endpoint").trim();
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
//            e.printStackTrace();
        }

        // 初始化一个OSSClient
        OSSClient client;
        if (!"production".equals(prop.getProperty("deploy.mode"))) {
            // 初始化一个OSSClient(非生产环境不需要设置服务器地址)
            client = new OSSClient(AccessKeyId, AccessKeySecret);
        } else {
            // 初始化一个OSSClient（生产环境设置阿里云的内网地址）
            client = new OSSClient(EndPoint, AccessKeyId, AccessKeySecret);
        }

        String outputFilePath;
        byte[] bytes;
        if(fileType == FileType.XLSX) {
            outputFilePath = tenantId + "/tmp/" + id + ".xlsx";
            try {
                bytes =  excel.getBytes();
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
//                e.printStackTrace();
                return null;
            }
        } else {
            outputFilePath = tenantId + "/tmp/" + id + ".xls";
            try {
                bytes = excel.getBytes();
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
//                e.printStackTrace();
                return null;
            }
        }
        InputStream content = new ByteArrayInputStream(bytes);

        // 创建上传Object的Metadata
        ObjectMetadata meta = new ObjectMetadata();

        // 必须设置ContentLength
        meta.setContentLength(bytes.length);

        // 上传Object.
        client.putObject(bucketName, outputFilePath, content, meta);

        String fileUrl = urlPath + outputFilePath;
        return fileUrl;
    }


    /**
     * 使用线程堆栈信息获取方法的调用者类名
     * @return 调用者类名
     */
    public static Class getCaller(int level){
        StackTraceElement stack[] = Thread.currentThread().getStackTrace();
        Class clazz;
        try {
            String name = stack[level].getClassName();
            clazz = Class.forName(name);
        }catch(Exception ex){
            ex.printStackTrace();
            clazz = Object.class;
        }
        return clazz;
    }
}
